/* 
 * This program is used in conjunction with fd_server to demonstrate
 * the use of the callback associated to a file/socket descriptor (see
 * fd_server.c). Running this example:
 *  > fd_server <cfg_file.xml>
 *  > fd_client <server_IP_addr> 
 * (server_IP_addr is printed by fd_server)
 *
 * ACK: This program is virtually identical to the client program available
 *  at: http://pont.net/socket/prog/udpClient.c
 *
 * NOTE: This program is i3 agnostic.
 */


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h> /* memset() */
#include <sys/time.h> /* select() */ 

#define REMOTE_SERVER_PORT 1500
#define MAX_MSG 100


int main(int argc, char *argv[]) 
{
#define MSG_SIZE 1024  
  int sd, rc, i;
  char payload[MSG_SIZE];
  struct sockaddr_in cliAddr, remoteServAddr;
  struct hostent *h;

  /* check command line args */
  if(argc < 2) {
    printf("usage : %s <server_IP_addr>\n", argv[0]);
    exit(1);
  }

  /* get server IP address (no check if input is IP address or DNS name */
  h = gethostbyname(argv[1]);
  if(h==NULL) {
    printf("%s: unknown host '%s' \n", argv[0], argv[1]);
    exit(1);
  }

  printf("%s: sending data to '%s' (IP : %s) \n", argv[0], h->h_name,
	 inet_ntoa(*(struct in_addr *)h->h_addr_list[0]));

  remoteServAddr.sin_family = h->h_addrtype;
  memcpy((char *) &remoteServAddr.sin_addr.s_addr, 
	 h->h_addr_list[0], h->h_length);
  remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT);

    printf("ip=%s, port=%d\n", 
	   inet_ntoa(remoteServAddr.sin_addr), remoteServAddr.sin_port);

  /* socket creation */
  sd = socket(AF_INET,SOCK_DGRAM,0);
  if(sd<0) {
    printf("%s: cannot open socket \n",argv[0]);
    exit(1);
  }
  
  /* bind any port */
  cliAddr.sin_family = AF_INET;
  cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  cliAddr.sin_port = htons(0);
  
  rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
  if(rc<0) {
    printf("%s: cannot bind port\n", argv[0]);
    exit(1);
  }

  /* send data */
  i = 0;
  while (1) {
    /* send a message every second */
    sleep(1);
    sprintf(payload, "%d", i++); 
    printf("%s\n", payload);
    rc = sendto(sd, payload, strlen(payload) + 1, 0, 
		(struct sockaddr *) &remoteServAddr, 
		sizeof(remoteServAddr));

    if(rc<0) {
      printf("%s: cannot send data %d \n", argv[0], i);
      close(sd);
      exit(1);
    }

  }
  
  return 1;
}

